package com.wmyg.tracker.sdk;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Slf4j
@Component
public class UltimateManager {

    @Autowired
    SmartManager smartManager;

    private Map<String, ThreadContext> localFabricS= new HashMap<>();

    public FabricResult invoke(String fcn, String[] args, Boolean isInvoke) {
        FabricResult fabricResult = null;
        String tag=Thread.currentThread().getName();
        FabricManager  fabric=getFabric(tag);
        if (null == fabric) {
            FabricManager mng = smartManager.createFabric(tag);
            localFabricS.put(tag, new ThreadContext(mng,Thread.currentThread()));
            if (isInvoke) {
                log.info("is invoke");
                fabricResult = mng.invoke(fcn, args);
            } else {
                log.info("is query");
                fabricResult = mng.query(fcn, args);
            }
        } else {
            log.info("Fabric Client : A thread {} exists, a old FabricManager is working.Thread count ={}" , tag,localFabricS.size() );
            fabricResult = fabric.invoke(fcn, args);
        }
        return fabricResult;
    }

    synchronized private FabricManager getFabric(String tag){

        ThreadContext cxt=localFabricS.get(tag);
        if(cxt==null){
            return null;
        }
        return cxt.getMng();
    }

    public  void checkTheadState() {

        ThreadContext item = null;
        String key = null;
        for (Iterator i = localFabricS.keySet().iterator(); i.hasNext(); ) {
            String tKey = (String) i.next();
            item = localFabricS.get(tKey);
            if (item.getThread().isAlive() == false) {
                key = tKey;
                break;
            }
        }
        if (key != null) {
            log.info("Fabric Client : A thread  was dead ={}", key);
            item =localFabricS.get(key);
            FabricManager fmang= item.getMng();
            fmang.abandon();
            localFabricS.remove(key);
        }
        // log.info("Upload case : checkTheadState()******* run once!", key);
    }

    class ThreadContext{


        public FabricManager getMng() {
            return mng;
        }
        public Thread getThread() {
            return thread;
        }


        private FabricManager mng;
        private Thread        thread;

        public  ThreadContext(FabricManager mng,Thread  thread){
            this.mng =mng;
            this.thread =thread;
        }


    }

}
